package com.serkol.ams.controller.api;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.serkol.ams.bean.MyPageOld;
import com.serkol.ams.bean.OrderUserShenheParam;
import com.serkol.ams.bean.Result;
import com.serkol.ams.entity.LoginLog;
import com.serkol.ams.entity.OrderDetail;
import com.serkol.ams.entity.OrderMaster;
import com.serkol.ams.entity.Users;
import com.serkol.ams.service.*;
import com.serkol.annotation.IsLogin;
import com.serkol.constant.AuthConstant;
import com.serkol.constant.ResultCode;
import com.serkol.constant.ResultConstant;
import com.serkol.exception.AuthException;
import com.serkol.exception.SucsessException;
import com.serkol.utils.OrderUtils;
import com.serkol.wx.service.WeChatPayService;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("api/order")
public class OrderApiController {
    @Value("${upload.host}")
    private String uploadhost;
    @Autowired
    private OrderMasterService masterService;
    @Autowired
    private OrderDetailService detailService;

    @Autowired
    private AgentInvitationRelationshipService agentInvitationRelationshipService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WeChatPayService weChatPayService;

    @Autowired
    private UsersService usersService;

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private PrintersService printersService;
    @Autowired
    private CloudInventoryService cloudInventoryService;

    @Autowired
    private UsersWalletService walletService;

    @IsLogin
    @GetMapping("/getInfo")
    @ResponseBody
    public Result getInfo() {

        Map<String, Object> info = masterService.getInfo();

        return Result.ok(info);
    }

    @IsLogin
    @GetMapping("/info")
    @ResponseBody
    public Result info(@RequestParam(name = "id", defaultValue = "0") long id) {
        AuthConstant.setPathUrl(uploadhost);
        Map<String, Object> info = masterService.info(id);

        return Result.ok(info);
    }


    @GetMapping("/findByMyList")
    public Result findByMyList(@RequestParam(name = "status", defaultValue = "0") int status) {
        AuthConstant.setPathUrl(uploadhost);
        Result result = new Result();
        List<Map<String, Object>> list = masterService.findByMyList(status);
        if (list.size() > 0) {
            result.setStatus(ResultConstant.SUCSESS);
            result.setData(list);
        } else {
            result.setStatus(ResultConstant.EMPTIY);
        }
        return result;
    }

    @IsLogin
    @Transactional
    @PostMapping("/newOrder")
    public Result newOrder(@RequestBody JSONObject object) throws AuthException, WxPayException, SucsessException {

        LoginLog loginLog = AuthConstant.getLoginLog();
        boolean save = false;

        long agentId = object.getLongValue("agentId");

        OrderMaster order = object.getObject("order", OrderMaster.class);
        order.setSn(OrderUtils.getOrderNum(loginLog.getUserId()));
        // order.setUserId(loginLog.getUserId());
        if (order.getIsUpgrade() != 2) {
            order.setUserId(loginLog.getUserId());
        }
        order.setOperatorId(loginLog.getUserId());
        order.setAgentId(agentId);
        order.setIsAgent(1);
        System.out.println(order);
        JSONArray details = object.getJSONArray("details");
        List<OrderDetail> orderDetails = details.toJavaList(OrderDetail.class);
  /*      save = masterService.saveAgentOrderDetails(order, orderDetails, agentId);

        if (save) {

            return Result.ok();
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }*/

        save = masterService.save(order);
        if (save) {
            List<OrderDetail> orderDetailsN = new ArrayList<>();
            Iterator<OrderDetail> iterator = orderDetails.iterator();
            StringBuilder sb = new StringBuilder();
            while (iterator.hasNext()) {
                OrderDetail next = iterator.next();
                next.setUserId(loginLog.getUserId());
                next.setOrderId(order.getId());
                next.setAddressId(order.getAddressId());
                orderDetailsN.add(next);
            }
            boolean b = detailService.saveBatch(orderDetailsN);
            if (b) {
                if (order.getPayType() == 1) {
                    boolean o = walletService.reNoChange("账号金额",order.getId(), order.getUserId(), order.getUserId(), order.getPaymentAmount(), 8);
                    if (o) {
                        boolean bb = orderNotify(order.getId());
                        return bb ? Result.ok() : Result.failure();
                    } else {
                        throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
                    }

                } else {
                    Object o = null;
                    o = weChatPayService.weChatPay(WxPayConstants.TradeType.JSAPI, "代理支付", order.getSn(), order.getPaymentAmount(), loginLog.getOpenId());

                    return Result.ok(o);
                }
            } else {
                throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
            }
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }

    }

    @IsLogin
    @Transactional
    @PostMapping("/createOrder")
    public Result createOrder(@RequestBody JSONObject object) throws AuthException, WxPayException, SucsessException {
        LoginLog loginLog = AuthConstant.getLoginLog();
        boolean save = false;

        //   long agentId = object.getLongValue("agentId");

        OrderMaster order = object.getObject("order", OrderMaster.class);
        order.setSn(OrderUtils.getOrderNum(loginLog.getUserId()));
        //  if(order.getIsUpgrade() != 2){
        order.setUserId(loginLog.getUserId());
        //   }

        order.setOperatorId(loginLog.getUserId());

        //   System.out.println(order);
        JSONArray details = object.getJSONArray("details");
        List<OrderDetail> orderDetails = details.toJavaList(OrderDetail.class);
  /*      save = masterService.saveAgentOrderCreateDetails(order, orderDetails);

        if (save) {

            return Result.ok();
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }*/
        save = masterService.save(order);
        if (save) {
            List<OrderDetail> orderDetailsN = new ArrayList<>();
            Iterator<OrderDetail> iterator = orderDetails.iterator();
            StringBuilder sb = new StringBuilder();
            while (iterator.hasNext()) {
                OrderDetail next = iterator.next();
                next.setUserId(loginLog.getUserId());
                next.setOrderId(order.getId());
                next.setAddressId(order.getAddressId());
                orderDetailsN.add(next);
            }
            boolean b = detailService.saveBatch(orderDetailsN);
            if (b) {
                if (order.getPayType() == 1) {
                    boolean o = walletService.reNoChange("账号金额",order.getId(), order.getUserId(), order.getUserId(), order.getPaymentAmount(), 8);
                    if (o) {
                        boolean bb = orderNotify(order.getId());
                        return bb ? Result.ok() : Result.failure();
                    } else {
                        throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
                    }

                } else {
                    Object o = null;
                    o = weChatPayService.weChatPay(WxPayConstants.TradeType.JSAPI, "代理支付", order.getSn(), order.getPaymentAmount(), loginLog.getOpenId());

                    return Result.ok(o);
                }
            } else {
                throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
            }
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }


    }

    @IsLogin
    @Transactional
    @PostMapping("/rePayment")
    public Result rePayment(@RequestParam(name = "id", defaultValue = "0") long id) throws WxPayException {
        LoginLog loginLog = AuthConstant.getLoginLog();
        if (id > 0) {
            OrderMaster order = masterService.findById(id);
            Object rO = weChatPayService.weChatPay(WxPayConstants.TradeType.JSAPI, "代理支付", order.getSn(), order.getPaymentAmount(), loginLog.getOpenId());
            return Result.ok(rO);
        } else {
            return Result.failure();
        }


    }

    @Transactional
    @PostMapping("/createBackOrder")
    public Result createbackOrder(@RequestBody JSONObject object) throws AuthException, WxPayException {
        LoginLog loginLog = AuthConstant.getLoginLog();
        boolean save = false;

        //   long agentId = object.getLongValue("agentId");

        OrderMaster order = object.toJavaObject(OrderMaster.class);
        System.out.println(order);
        order.setSn(OrderUtils.getOrderNum(order.getUserId()));
        //  if(order.getIsUpgrade() != 2){
        //  order.setUserId(loginLog.getUserId());
        //   }

        order.setOperatorId(loginLog.getUserId());

        //   System.out.println(order);
        JSONArray details = object.getJSONArray("goods");
        List<OrderDetail> orderDetails = details.toJavaList(OrderDetail.class);
  /*      save = masterService.saveAgentOrderCreateDetails(order, orderDetails);

        if (save) {

            return Result.ok();
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }*/
        order.setIsPay(1);
        if (order.getCloudType() == 1) {
            order.setStatus(3);
        } else {
            order.setStatus(2);
        }

        //    order.setP
        save = masterService.save(order);
        if (save) {
            List<OrderDetail> orderDetailsN = new ArrayList<>();
            Iterator<OrderDetail> iterator = orderDetails.iterator();
            StringBuilder sb = new StringBuilder();
            while (iterator.hasNext()) {
                OrderDetail next = iterator.next();
                next.setUserId(order.getUserId());
                next.setOrderId(order.getId());
                next.setAddressId(order.getAddressId());
                orderDetailsN.add(next);
            }
            boolean b = detailService.saveBatch(orderDetailsN);
            if (b) {
                boolean autoByUpdate = masterService.findAutoByUpdate(order.getUserId());
                if (order.getCloudType() == 1) {
                    boolean cb = cloudInventoryService.saveOrder(orderDetailsN);
                }
                return Result.ok();
            } else {
                throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
            }
        } else {
            throw new AuthException(ResultCode.REQUEST_ERROR_PAYMENT_REQUIRED);
        }


    }

    @IsLogin
    @GetMapping("/findByPageList")
    public Result findByPageList(@RequestParam(name = "pageSize", defaultValue = "10") int pageSize, @RequestParam(name = "current", defaultValue = "0") int current
            , @RequestParam(name = "type", defaultValue = "-1") int type
            , @RequestParam(name = "paymentMethod", defaultValue = "0") int paymentMethod
            , @RequestParam(name = "paymentStatus", defaultValue = "0") int paymentStatus
            , @RequestParam(name = "userName", defaultValue = "") String userName
            , @RequestParam(name = "sn", defaultValue = "") String sn
            , @RequestParam(name = "partySn", defaultValue = "") String partySn) {

        //paymentMethod,paymentStatus,userName,sn,partySn,date

        Result result = new Result();
        return masterService.findByPageList(pageSize, current, type, paymentMethod, paymentStatus, userName.trim(), sn.trim(), partySn.trim());

    }

    @IsLogin
    @GetMapping("/findGoodsList")
    public Result findGoodsList(
            @RequestParam(name = "userId", defaultValue = "0") long userId) {
        if (userId > 0) {
            Users byId = usersService.getById(userId);
            System.out.println(byId);
            List<Map<String, Object>> data = goodsService.findGoodsList(byId.getAgentId());
            return Result.ok(data);
        } else {
            return Result.failure();
        }
    }


    @GetMapping("/findByOrderDetailList")
    public Result findByOrderDetailList(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId) {
        Result result = new Result();
        List<Map<String, Object>> list = detailService.findByOrderDetailList(orderId);
        if (list.size() > 0) {
            result.setStatus(ResultConstant.SUCSESS);
            result.setData(list);
        } else {
            result.setStatus(ResultConstant.EMPTIY);
        }
        return result;
    }

    @IsLogin
    @PostMapping("/adminPayment")
    public Result adminPayment(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId) throws AuthException, SucsessException {
        LoginLog loginLog = AuthConstant.getLoginLog();

        System.out.println("ORDERID:" + orderId);
        //    masterService.findById()
        if (orderId > 0) {
            OrderMaster orderMaster = masterService.findById(orderId);
            if (orderMaster != null) {
                List<OrderDetail> byOrderDetailList = detailService.findByOrderList(orderMaster.getId());
                boolean save = false;
                if (orderMaster.getIsAgent() == 1) {
                    save = masterService.saveAgentOrderDetails(orderMaster, byOrderDetailList, orderMaster.getAgentId());
                } else {
                    //  save = masterService.saveAgentOrderCreateDetails(orderMaster, byOrderDetailList);
                    if (orderMaster.getIsUpgrade() == 1) {
                        save = masterService.saveAgentOrderCreateDetails(orderMaster, byOrderDetailList);
                    } else {
                        OrderDetail orderDetail = byOrderDetailList.get(0);
                        if (orderDetail.getGoodsId() == 35 || orderDetail.getGoodsId() == 34) {
                            save = true;
                        } else {
                            //save=masterService.agentDanTarget(orderMaster,byOrderDetailList);
                            save = masterService.saveOrderCreate(orderMaster, byOrderDetailList);
                        }

                    }
                }
                if (save) {
                    System.out.println("save");
                    System.out.println(orderMaster.getCloudType());
                    System.out.println(orderMaster.getCloudType() == 1);
                    if (orderMaster.getCloudType() == 1) {
                        boolean cb = cloudInventoryService.saveOrder(byOrderDetailList);
                    }
                }
                return getResult(loginLog, orderMaster, save);
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }


    }

    @IsLogin
    @PostMapping("/shopPayment")
    public Result shopPayment(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId) throws AuthException, SucsessException {
        LoginLog loginLog = AuthConstant.getLoginLog();

        System.out.println("ORDERID:" + orderId);
        //    masterService.findById()
        if (orderId > 0) {
            OrderMaster orderMaster = masterService.findById(orderId);
            if (orderMaster != null) {
                List<OrderDetail> byOrderDetailList = detailService.findByOrderList(orderMaster.getId());
                boolean save = false;
                if (orderMaster.getIsAgent() == 1) {
                    save = masterService.saveAgentOrderDetails(orderMaster, byOrderDetailList, orderMaster.getAgentId());
                } else {
                    //  save = masterService.saveAgentOrderCreateDetails(orderMaster, byOrderDetailList);
                    if (orderMaster.getIsUpgrade() == 1) {
                        save = masterService.saveAgentOrderCreateDetails(orderMaster, byOrderDetailList);
                    } else {
                        OrderDetail orderDetail = byOrderDetailList.get(0);
                        if (orderDetail.getGoodsId() == 35 || orderDetail.getGoodsId() == 34) {
                            save = true;
                        } else {
                            //save=masterService.agentDanTarget(orderMaster,byOrderDetailList);
                            save = masterService.saveOrderCreate(orderMaster, byOrderDetailList);
                        }

                    }
                }
                if (save) {
                    System.out.println("save");
                    System.out.println(orderMaster.getCloudType());
                    System.out.println(orderMaster.getCloudType() == 1);
                    if (orderMaster.getCloudType() == 1) {
                        boolean cb = cloudInventoryService.saveOrder(byOrderDetailList);
                    }
                }
                return getResult(loginLog, orderMaster, save);
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }


    }

    @IsLogin
    @PostMapping("/cloudDelivery")
    public Result cloudDelivery(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId) throws AuthException {
        LoginLog loginLog = AuthConstant.getLoginLog();

        System.out.println("ORDERID:" + orderId);
        //    masterService.findById()
        if (orderId > 0) {
            OrderMaster orderMaster = masterService.findById(orderId);


            if (orderMaster != null) {
                List<OrderDetail> byOrderDetailList = detailService.findByOrderList(orderMaster.getId());

                boolean save = false;

                save = masterService.savecloudDeliveryOrderDetails(orderMaster);

                if (save) {
                    orderMaster.setPaymentDate(new Date());
                    //         orderMaster.setPartySn(wxPayOrderNotifyResult.getTransactionId());
                    orderMaster.setPaymentStatus(2);
                    orderMaster.setStatus(2);
                    orderMaster.setIsPay(1);
                    orderMaster.setPaymentMethod(3);

                    orderMaster.setOperatorId(loginLog.getUserId());

                    // masterService.updateById(orderMaster);
                    boolean b = masterService.updateById(orderMaster);
                    if (b) {
                        if (orderMaster.getCloudType() == 1) {
                            boolean cb = cloudInventoryService.saveOrder(byOrderDetailList);
                        }
                    }
                }
                return save ? Result.ok() : Result.failure();
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }


    }


    @IsLogin
    @PostMapping("/cancelOrder")
    public Result cancelOrder(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId) {
        LoginLog loginLog = AuthConstant.getLoginLog();

        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setId(orderId);
        //orderMaster.setIsPay(0);
        //  orderMaster.setPaymentDate(new Date());
        // orderMaster.setPaymentMethod(6);
        orderMaster.setPaymentStatus(3);
        orderMaster.setStatus(4);
        orderMaster.setOperatorId(loginLog.getUserId());
        boolean b = masterService.updateById(orderMaster);
        if (b) {
            return Result.ok();
        } else {
            return Result.failure();
        }

    }

    @IsLogin
    @PostMapping("/shipments")
    public Result shipments(
            @RequestParam(name = "orderId", defaultValue = "0") long orderId,
            @RequestParam(name = "postNUm", defaultValue = "") String postNUm) {
        LoginLog loginLog = AuthConstant.getLoginLog();

        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setId(orderId);
        //orderMaster.setIsPay(0);
        //  orderMaster.setPaymentDate(new Date());
        // orderMaster.setPaymentMethod(6);
        //   orderMaster.setPaymentStatus(3);
        if (StringUtils.isNotEmpty(postNUm)) {
            orderMaster.setPostNum(postNUm);
        }
        orderMaster.setStatus(3);
        orderMaster.setOperatorId(loginLog.getUserId());
        boolean b = masterService.updateById(orderMaster);
        if (b) {
            return Result.ok();
        } else {
            return Result.failure();
        }

    }

    @IsLogin
    @PostMapping("/shenhePayment")
    public Result shenhePayment(
            @RequestBody JSONObject datas) throws AuthException {
        LoginLog loginLog = AuthConstant.getLoginLog();
        long orderId = datas.getLongValue("orderId");
        JSONArray datas1 = datas.getJSONArray("datas");
        List<OrderUserShenheParam> orderUserShenheParams = datas1.toJavaList(OrderUserShenheParam.class);
        System.out.println("ORDERID:" + orderId);
        System.out.println(datas);
        //    masterService.findById()
        if (orderId > 0) {
            OrderMaster orderMaster = masterService.findById(orderId);


            if (orderMaster != null) {
                boolean save = false;
                save = masterService.saveShenheOrderDetails(orderMaster, orderUserShenheParams);

                return getResult(loginLog, orderMaster, save);
            } else {
                return Result.failure();
            }
        } else {
            return Result.failure();
        }


    }


    @PostMapping("/updateAuto")
    public Result updateAuto(
    ) {
        boolean autoUpdate = masterService.findAutoUpdate();

        return autoUpdate ? Result.ok() : Result.failure();
    }

    @PostMapping("/updateByAuto")
    public Result updateByAuto(
            // @RequestParam(name = "userId", defaultValue = "0") long userId
    ) {
        boolean autoUpdate = masterService.findAutoByUpdate(235);

        return autoUpdate ? Result.ok() : Result.failure();
    }


    private Result getResult(LoginLog loginLog, OrderMaster orderMaster, boolean save) {
        if (save) {
            orderMaster.setPaymentDate(new Date());
            //         orderMaster.setPartySn(wxPayOrderNotifyResult.getTransactionId());
            if(orderMaster.getPaymentStatus()==null) {
                orderMaster.setPaymentStatus(2);
            }
            orderMaster.setStatus(2);
            orderMaster.setIsPay(1);
           // orderMaster.setPaymentMethod(6);
            if(orderMaster.getPaymentMethod()==null) {
                orderMaster.setPaymentMethod(2);
            }

            orderMaster.setOperatorId(loginLog.getUserId());

            boolean b = masterService.updateById(orderMaster);
            if (b) {

                printersService.sendPrinter(orderMaster.getId());
            }
        }
        return save ? Result.ok(orderMaster) : Result.failure();
    }


    public boolean orderNotify(long orderId) throws AuthException, SucsessException {
        System.out.println("--------------------------------------------------------");
        OrderMaster order= masterService.findById(orderId);
        //     OrderMaster order = masterService.getBySn(wxPayOrderNotifyResult.getOutTradeNo());
        if (order.getIsPay() != 1) {

            List<OrderDetail> byOrderDetailList = detailService.findByOrderList(order.getId());
            boolean save = false;
            if (order.getIsAgent() == 1) {
                save = masterService.saveAgentOrderDetails(order, byOrderDetailList, order.getAgentId());
            } else {
                if (order.getIsUpgrade() == 1) {
                    save = masterService.saveAgentOrderCreateDetails(order, byOrderDetailList);
                } else {
                    save = masterService.saveOrderCreate(order, byOrderDetailList);

                }
            }
            if (save) {
                order.setIsPay(1);
                order.setPaymentDate(new Date());
                //   order.setPartySn(wxPayOrderNotifyResult.getTransactionId());
                order.setPaymentStatus(8);
                order.setStatus(2);
                boolean b = masterService.updateById(order);
                if (b) {
                    if (order.getCloudType() == 1) {
                        boolean cb = cloudInventoryService.saveOrder(byOrderDetailList);
                    }
                    printersService.sendPrinter(order.getId());
                }


            }
            return save;


        } else {
            return true;
        }

    }

}
